package com.hs.srm.admin.modules.orders.service.impl;

import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.TemplateExportParams;
import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.hs.srm.admin.common.util.OANoticeUtil;
import com.hs.srm.admin.modules.orders.dao.ScmPoHeaderDao;
import com.hs.srm.admin.modules.orders.dao.ScmPoItemDao;
import com.hs.srm.admin.modules.orders.entity.DeliverRecordEntity;
import com.hs.srm.admin.modules.orders.entity.OrderFileEntity;
import com.hs.srm.admin.modules.orders.entity.ScmPoItemEntity;
import com.hs.srm.admin.modules.orders.service.DeliverRecordService;
import com.hs.srm.admin.modules.orders.service.OrderFileService;
import com.hs.srm.admin.modules.orders.service.ScmPoItemService;
import com.hs.srm.admin.modules.orders.vo.ProScmPoItemVo;
import com.hs.srm.admin.modules.orders.vo.ScmPoItemVo;
import com.hs.srm.admin.modules.orders.vo.ScmPoitemDeliverVO;
import com.hs.srm.admin.modules.quota.dao.QuotaDao;
import com.hs.srm.admin.modules.quota.dao.QuotaHistoryDao;
import com.hs.srm.admin.modules.requisition.dao.NproPurchRequestItemDao;
import com.hs.srm.admin.modules.requisition.dao.ProPurchRequestItemDao;
import com.hs.srm.admin.modules.requisition.dao.SamplePurchRequestItemDao;
import com.hs.srm.admin.modules.requisition.entity.NproPurchRequestItemEntity;
import com.hs.srm.admin.modules.requisition.entity.ProPurchRequestItemEntity;
import com.hs.srm.admin.modules.requisition.entity.SamplePurchRequestItemEntity;
import com.hs.srm.admin.modules.sampletest.dao.UploadFileRemarkDao;
import com.hs.srm.admin.modules.sampletest.entity.UploadFileRemarkEntity;
import com.hs.srm.base.common.config.SysConfig;
import com.hs.srm.base.common.utils.EntityUtils;
import com.hs.srm.base.common.utils.QueryParam;
import com.hs.srm.common.utils.PageUtils;
import com.hs.srm.common.utils.R;
import com.landray.kmss.km.review.webservice.Exception_Exception;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.ResponseBody;
import sunnykid.character.UtilCharacter;
import sunnykid.text.SunnykidText;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 采购订单行项目Service实现
 *
 * @author Sunnykid
 * @date 2019年3月17日
 */
@Service("scmPoItemService")
@Transactional
public class ScmPoItemServiceImpl extends ServiceImpl<ScmPoItemDao, ScmPoItemEntity> implements ScmPoItemService {

    @Autowired
    private ScmPoItemDao scmPoItemDao;

    @Autowired
    private ScmPoHeaderDao scmPoHeaderDao;

    @Autowired
    private NproPurchRequestItemDao nproPurchRequestItemDao;

    @Autowired
    private ProPurchRequestItemDao proPurchRequestItemDao;

    @Autowired
    private SamplePurchRequestItemDao samplePurchRequestItemDao;

    @Autowired
    private QuotaDao quotaDao;

    @Autowired
    private QuotaHistoryDao quotaHistoryDao;

    @Autowired
    private DeliverRecordService deliverRecordService;

    @Autowired
    private OrderFileService orderFileService;
    @Autowired
    private UploadFileRemarkDao uploadFileRemarkDao;

    @Override
    public PageUtils selectDetailPage(Map<String, Object> params) {
        List<String> ids = new ArrayList<String>();
        List<String> status = new ArrayList<String>();
        String idss[] = null;
        String statuss[] = null;
        String idsstr = "";
        String statusstr = "";
        if (params.get("ids") != null) {
            idsstr = params.get("ids").toString();
            idss = idsstr.split(",");
            for (int i = 0; i < idss.length; i++) {
                ids.add(idss[i]);
            }
            params.put("ids", ids);
        }
        if (params.get("status") != null) {
            statusstr = params.get("status").toString();
            statuss = statusstr.split(",");
            for (int i = 0; i < statuss.length; i++) {
                if (statuss[i].equals("-1") || statuss[i].equals("0")) {
                    status.add(statuss[i]);
                }
            }
            params.put("status", status);
        }

        Page<ScmPoItemVo> page = this.selectDetailPage(new QueryParam<ScmPoItemVo>(params).getPage(),
                new EntityWrapper<ScmPoItemVo>(), params);
        return new PageUtils(page);
    }

    private Page<ScmPoItemVo> selectDetailPage(Page<ScmPoItemVo> page, Wrapper<ScmPoItemVo> wrapper,
                                               Map<String, Object> params) {
        page.setRecords(this.baseMapper.selectDetailPage(page, wrapper, params));
        return page;
    }

    @Override
    public List<ScmPoItemEntity> getByPoNo(String poNo) {
        return this.scmPoItemDao.getByPoNo(poNo);
    }


    @Override
    public ScmPoItemVo selectByIdVo(String pkId) {
        return this.scmPoItemDao.selectByIdVo(pkId);
    }

    @Override
    public ScmPoItemEntity selectById(String pkId) {
        return this.baseMapper.selectById(pkId);
    }

    @Override
    public boolean updateById(ScmPoItemEntity scmPoItemEntity) {
        boolean flg = false;
        int flgtem = this.baseMapper.updateById(scmPoItemEntity);
        if (flgtem > 0) {
            flg = true;
        }
        return flg;
    }

    @Override
    public ScmPoItemEntity selectByPoItem(String poNo, String itemPo) {
        EntityWrapper<ScmPoItemEntity> queryWrapper = new EntityWrapper<>();
        queryWrapper.eq("po_no", poNo).eq("item_no", itemPo);
        ScmPoItemEntity scmPoItemEntity = this.selectOne(queryWrapper);
        return scmPoItemEntity;
    }

    //保存上传文件路径
    @Override
    public Integer saveUploadFilePath(HttpServletRequest request, String filePath) {
        Integer result = null;
        UploadFileRemarkEntity ufrEntity = new UploadFileRemarkEntity();
        String poItemId = request.getParameter("poItemId");
        ufrEntity.setPoItemId(poItemId);
        //备注
        String remark = request.getParameter("remark");
        ufrEntity.setRemark(remark);
        //上传类型
        String uploadType = request.getParameter("uploadType");
        ufrEntity.setFileType(uploadType);
        ufrEntity.setFilepath(filePath);
        String uploadId = SunnykidText.getUUID();
        ufrEntity.setUploadId(uploadId);
        result = this.uploadFileRemarkDao.insert(ufrEntity);
        return result;
    }

    //更新订单变更信息
    @Override
    public boolean updateOrderInfoById(ScmPoItemEntity itemEntity) {
        int row = scmPoItemDao.updateOrderInfoById(itemEntity);
        boolean result = false;
        if (row != 0) {
            result = true;
        }
        return result;
    }

    //删除订单
    @Override
    public String deleteOrders(String type, String[] itemIds) {
        List<ScmPoItemEntity> poItemList = scmPoItemDao.selectBatchIds(Arrays.asList(itemIds));
        //非生产性
        NproPurchRequestItemEntity nproEntity;
        //生产性
        ProPurchRequestItemEntity proEntity;
        //样品
        SamplePurchRequestItemEntity sampleEntity;
        //通过po_no修改header表中delete_flag实现逻辑删除，通过item_uuid修改request_item表中goods_status申请单恢复草稿状态
        for (ScmPoItemEntity itemEntity : poItemList) {
            //根据 采购申请编号purchRequestCode、行项目号purchRequestItemCode，找出同一批订单全删，并且从配额取值生产性订单的要改回配额
            List<ScmPoItemEntity> itemList = scmPoItemDao.getItemListByPurchRequest(itemEntity.getPrNo(), itemEntity.getPrItemNo());

            //判断itemList中item是否都是草稿、驳回状态
            for (ScmPoItemEntity item : itemList) {
                //itemStatus不是草稿（0），不是驳回（-1）则不能删除订单
                if (!item.getItemStatus().equals("0") && !item.getItemStatus().equals("-1")) {
                    return "关联的订单含有非草稿、驳回状态不能删除！";
                }
            }

            for (ScmPoItemEntity scmPoItemEntity : itemList) {
                //scm_po_item逻辑删除
                scmPoItemDao.updateItemDeleteFlag(scmPoItemEntity.getPoNo(), scmPoItemEntity.getItemNo());
                //非生产性
                if (type.equals("NPRO")) {
                    nproEntity = new NproPurchRequestItemEntity();
                    nproEntity.setGoodsStatus(NproPurchRequestItemEntity.CAOGAO);
                    nproPurchRequestItemDao.update(nproEntity, new EntityWrapper<NproPurchRequestItemEntity>().eq("pk_id", scmPoItemEntity.getItemUuid()));
                    //生产性
                } else if (type.equals("PRO")) {
                    proEntity = new ProPurchRequestItemEntity();
                    proEntity.setGoodsStatus(ProPurchRequestItemEntity.CAOGAO);
                    proPurchRequestItemDao.update(proEntity, new EntityWrapper<ProPurchRequestItemEntity>().eq("pk_id", scmPoItemEntity.getItemUuid()));
                    //订单来自配额，删除订单还原配额量
                    if (scmPoItemEntity.getFromQuotaFlag().equals("true")) {
                        //查询供应商编码,物料编码,工厂代码,发货总量 还原对应的配额
                        ProScmPoItemVo proScmPoItemVo = scmPoItemDao.selectScmVOByParams(scmPoItemEntity.getPoItemId());
                        int result = quotaDao.returnQuotaNum(proScmPoItemVo);
                        //配额数据已过期，被移动至配额历史记录表中，修改历史记录表配额数
                        if (result == 0) {
                            quotaHistoryDao.returnQuotaNum(proScmPoItemVo);
                        }
                    }
                    //样品订单
                } else if (type.equals("SAMPLE")) {
                    sampleEntity = new SamplePurchRequestItemEntity();
                    sampleEntity.setGoodsStatus(SamplePurchRequestItemEntity.CAOGAO);
                    samplePurchRequestItemDao.update(sampleEntity, new EntityWrapper<SamplePurchRequestItemEntity>().eq("pk_id", scmPoItemEntity.getItemUuid()));
                }
            }
        }
        return null;
    }

    /**
     * 发货后通知下单人
     *
     * @param itemEntityList  发货订单list
     * @param isBatchDelivery 是否分批发货
     */
    @Override
    public void noticeApplier(List<ScmPoItemEntity> itemEntityList, boolean isBatchDelivery) throws Exception_Exception {
        String str = null;
        String content = null;
        for (ScmPoItemEntity item : itemEntityList) {
            str = OANoticeUtil.isOAccountBlank(item.getPrNo());
            //返回值不空，表示OA账号不存在，则不通知下单人
            if (StringUtils.isNotBlank(str)) {
                continue;
            }
            content = "您申请的: " + item.getMaterialDesc() + " 已发货！";
            if (isBatchDelivery) {
                content = "您申请的: " + item.getMaterialDesc() + " 已分批发货！";
            }
            OANoticeUtil.remindCreator(item.getPrNo(), content, "请购申请发货通知");
        }
    }

    /**
     * 根据pkId找到pono，查询pono对应的数据有几条同步SAP了
     *
     * @param id
     * @return
     */
    @Override
    public int getSendSAPCountById(String id) {
        return scmPoItemDao.getSendSAPCountById(id);
    }

    /**
     * 生成送货单
     *
     * @param pkIds 订单id
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @ResponseBody
    @Override
    public R deliverOrder(List<String> pkIds) throws IOException {
        //先检查选中的item是否都有发货记录
        for (String id : pkIds) {
            int count = deliverRecordService.selectCount(new EntityWrapper<DeliverRecordEntity>().eq("po_item_id", id).eq("is_record", 0));
            if (count == 0) {
                ScmPoItemEntity scmPoItemEntity = scmPoItemDao.selectById(id);
                return R.error("采购凭证号 " + scmPoItemEntity.getPoNo() + " 不存在发货记录，请确认！");
            }
        }
        List<ScmPoitemDeliverVO> list = scmPoItemDao.deliverOrderData(pkIds);
        //将采购组 单位转换成文本
        list = EntityUtils.valToTxt(list);
        //保存写入模板数据
        Map<String, Object> map = new HashMap<>();
        List<Map<String, Object>> mapList = new ArrayList<>();
        //object to map
        list.forEach(item -> mapList.add(BeanUtil.beanToMap(item)));
        //添加序号
        for (int i = 0; i < mapList.size(); i++) {
            mapList.get(i).put("index", i + 1);
        }
        map.put("mapList", mapList);
        map.put("vendorName", list.get(0).getVendorName());
        map.put("deliverCode", new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()));
        map.put("deliverDate", new SimpleDateFormat("yyyy年MM月dd日").format(new Date()));
        //数据写入Excel
        TemplateExportParams params = new TemplateExportParams(SysConfig.getExportTemplatePath() + UtilCharacter.FILE_SEPARATOR + "deliveryOrderTemplate.xls");
        Workbook workbook = ExcelExportUtil.exportExcel(params, map);
        //发货单保存路径
        String fileDir = SysConfig.getUploadPath() + "/orders/";
        File saveFile = new File(fileDir);
        if (!saveFile.exists()) {
            saveFile.mkdirs();
        }
        String fileName = "发货单" + new SimpleDateFormat("_yyyyMMddHHmmss").format(new Date()) + ".xls";
        FileOutputStream fos = new FileOutputStream(fileDir + fileName);
        workbook.write(fos);
        fos.close();
        //生成送货单后将发货记录表字段is_record修改为1：该发货记录已生成送货单
        deliverRecordService.updateIsRecord(list.stream().map(ScmPoitemDeliverVO::getDelieverId).collect(Collectors.toList()));
        //保存发货单信息
        List<OrderFileEntity> OrderFileList = new ArrayList<>();
        list.stream().map(ScmPoitemDeliverVO::getPoItemId).distinct().collect(Collectors.toList()).forEach(poItemId -> OrderFileList.add(new OrderFileEntity(poItemId, fileName, "/orders/" + fileName, new Date())));
        orderFileService.insertBatch(OrderFileList);
        //将订单送货明细改为1：已生成送货单
        scmPoItemDao.updateDeliverFile(list.stream().map(ScmPoitemDeliverVO::getPoItemId).collect(Collectors.toList()));
        //返回一个文件id，前端下载使用
        return R.ok(OrderFileList.get(0).getPkId());
    }
}
